home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 15 / CU Amiga Magazine's Super CD-ROM 15 (1997)(EMAP Images)(GB)[!][issue 1997-10].iso / CUCD / Graphics / Ghostscript / source / gs_res.ps < prev    next >
Encoding:
Text File  |  1997-06-18  |  18.0 KB  |  648 lines

  1. %    Copyright (C) 1994, 1996, 1997 Aladdin Enterprises.  All rights reserved.
  2. % This file is part of Aladdin Ghostscript.
  3. % Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  4. % or distributor accepts any responsibility for the consequences of using it,
  5. % or for whether it serves any particular purpose or works at all, unless he
  6. % or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  7. % License (the "License") for full details.
  8. % Every copy of Aladdin Ghostscript must include a copy of the License,
  9. % normally in a plain ASCII text file named PUBLIC.  The License grants you
  10. % the right to copy, modify and redistribute Aladdin Ghostscript, but only
  11. % under certain conditions described in the License.  Among other things, the
  12. % License requires that the copyright notice and this notice be preserved on
  13. % all copies.
  14.  
  15. % Initialization file for Level 2 resource machinery.
  16. % When this is run, systemdict is still writable,
  17. % but (almost) everything defined here goes into level2dict.
  18.  
  19. level2dict begin
  20.  
  21. (BEGIN RESOURCES) VMDEBUG
  22.  
  23. % We keep track of (global) instances with another entry in the resource
  24. % dictionary, an Instances dictionary.  For categories with implicit
  25. % instances, the values in Instances are the same as the keys;
  26. % for other categories, the values are [instance status size].
  27.  
  28. % Note that the dictionary that defines a resource category is stored
  29. % in global memory.  The PostScript manual says that each category must
  30. % manage global and local instances separately.  However, objects in
  31. % global memory other than systemdict can't reference objects in local memory.
  32. % This means that the resource category dictionary, which would otherwise be
  33. % the obvious place to keep track of the instances, can't be used to keep
  34. % track of local instances.  Instead, we define a dictionary in local VM
  35. % called localinstancedict, in which the key is the category name and
  36. % the value is the analogue of Instances for local instances.
  37.  
  38. % We don't currently implement automatic resource unloading.
  39. % When and if we do, it should be hooked to the garbage collector.
  40. % However, Ed Taft of Adobe says their interpreters don't implement this
  41. % either, so we aren't going to worry about it for a while.
  42.  
  43. currentglobal false setglobal systemdict begin
  44.   /localinstancedict 5 dict def
  45. end true setglobal
  46. /.emptydict 0 dict readonly def
  47. setglobal
  48.  
  49. % Resource category dictionaries have the following keys (those marked with
  50. % * are optional):
  51. %    Standard, defined in the Red Book:
  52. %        Category (name)
  53. %        *InstanceType (name)
  54. %        DefineResource
  55. %            <key> <instance> DefineResource <instance>
  56. %        UndefineResource
  57. %            <key> UndefineResource -
  58. %        FindResource
  59. %            <key> FindResource <instance>
  60. %        ResourceStatus
  61. %            <key> ResourceStatus <status> <size> true
  62. %            <key> ResourceStatus false
  63. %        ResourceForAll
  64. %            <template> <proc> <scratch> ResourceForAll -
  65. %        *ResourceFileName
  66. %            <key> <scratch> ResourceFileName <filename>
  67. %    Additional, specific to our implementation:
  68. %        Instances (dictionary)
  69. %        .LocalInstances
  70. %            - .LocalInstances <dict>
  71. %        .GetInstance
  72. %            <key> .GetInstance <instance> -true-
  73. %            <key> .GetInstance -false-
  74. %        .CheckResource
  75. %            <key> <value> .CheckResource <key> <value> <ok>
  76. %              (or may give an error if not OK)
  77. %        .DoLoadResource
  78. %            <key> .DoLoadResource - (may give an error)
  79. %        .LoadResource
  80. %            <key> .LoadResource - (may give an error)
  81. %        .ResourceFile
  82. %            <key> .ResourceFile <file> -true-
  83. %            <key> .ResourceFile <key> -false-
  84. % All the above procedures expect that the top dictionary on the d-stack
  85. % is the resource dictionary.
  86.  
  87. % Define enough of the Category category so we can define other categories.
  88. % The dictionary we're about to create will become the Category
  89. % category definition dictionary.
  90.  
  91. /.findcategory        % <name> .findcategory <category>
  92.  { { /Category findresource } stopped { pop stop } if
  93.  } bind def
  94.  
  95. /.resourceexec        % <key> /xxxResource .resourceexec -
  96.  {            %   (also pops the category from the dstack)
  97.    load stopped { Category end stop } if end
  98.  } bind def
  99.  
  100. 12 dict begin
  101.  
  102.         % Standard entries
  103.  
  104. /Category /Category def
  105. /InstanceType /dicttype def
  106.  
  107. /DefineResource
  108.     { .CheckResource
  109.        { dup /Category 3 index cvlit .growput
  110.         % We would like to make Category dictionaries read-only,
  111.         % and we used to do that here, but we can't do it,
  112.         % because we have to be able to replace the dummy, empty
  113.         % Instances dictionary with the real one later.
  114.          dup [ exch 0 -1 ] exch
  115.          Instances 4 2 roll put
  116.        }
  117.        { /defineresource load /typecheck signalerror
  118.        }
  119.       ifelse
  120.     } bind def
  121. /FindResource        % (redefined below)
  122.     { Instances exch get 0 get
  123.     } bind def
  124.  
  125.         % Additional entries
  126.  
  127. /Instances 25 dict def
  128. Instances /Category [currentdict 0 -1] put
  129.  
  130. /.LocalInstances 0 dict def
  131. /.GetInstance
  132.     { Instances exch .knownget
  133.     } bind def
  134. /.CheckResource
  135.     { dup gcheck currentglobal and
  136.        { /DefineResource /FindResource /ResourceForAll /ResourceStatus
  137.          /UndefineResource }
  138.        { 2 index exch known and }
  139.       forall
  140.       not { /defineresource load /invalidaccess signalerror } if
  141.       true
  142.     } bind def
  143.  
  144. Instances end begin    % for the base case of findresource
  145.  
  146. (END CATEGORY) VMDEBUG
  147.  
  148. % Define the resource operators.  We use the "stack protection" feature of
  149. % odef to make sure the stacks are restored properly on an error.
  150. % This requires that the operators not pop anything from the stack until
  151. % they have executed their logic successfully.  We can't make this
  152. % work for resourceforall, but we can make it work for the others.
  153.  
  154. mark
  155. /defineresource {    % <key> <instance> <category> defineresource <instance>
  156.     3 copy .findcategory dup begin
  157.     /InstanceType known {
  158.       dup type InstanceType ne {
  159.         dup type /packedarraytype eq InstanceType /arraytype eq and
  160.         not { /defineresource load /typecheck signalerror } if
  161.       } if
  162.     } if
  163.     /DefineResource .resourceexec
  164.     4 1 roll pop pop pop
  165. }
  166. /findresource {        % <key> <category> findresource <instance>
  167.     2 copy dup /Category eq
  168.       { pop //Category 0 get } { .findcategory } ifelse
  169.     begin
  170.     /FindResource .resourceexec exch pop exch pop
  171. }
  172. /resourceforall {    % <template> <proc> <scratch> <category> resourceforall -
  173.     .findcategory begin /ResourceForAll .resourceexec
  174. }
  175. /resourcestatus {    % <key> <category> resourcestatus <status> <size> true
  176.             % <key> <category> resourcestatus false
  177.     2 copy .findcategory begin /ResourceStatus .resourceexec
  178.      { 4 2 roll pop pop true } { pop pop false } ifelse
  179. }
  180. /undefineresource {    % <key> <category> undefineresource -
  181.     2 copy .findcategory begin /UndefineResource .resourceexec pop pop
  182. }
  183. end        % Instances of Category
  184. counttomark 2 idiv { bind odef } repeat pop
  185.  
  186. % Define the system parameters used for the Generic implementation of
  187. % ResourceFileName.
  188. systemdict begin
  189. currentdict /systemparams known not { /systemparams 10 dict readonly def } if
  190. systemparams
  191.   dup /FontResourceDir (/Resource/Font/) readonly .forceput
  192.   dup /GenericResourceDir (/Resource/) readonly .forceput
  193.   dup /GenericResourcePathSep (/) readonly .forceput
  194. pop
  195. end
  196.  
  197. % Define the generic algorithm for computing resource file names.
  198. /.rfnstring 100 string def
  199. /.genericrfn        % <key> <scratch> <prefix> .genericrfn <filename>
  200.  { 3 -1 roll //.rfnstring cvs concatstrings exch copy
  201.  } bind def
  202.  
  203. % Define the Generic category.
  204.  
  205. /Generic mark
  206.  
  207.         % Standard entries
  208.  
  209. % We're still running in Level 1 mode, so dictionaries won't expand.
  210. % Leave room for the /Category entry.
  211. /Category null
  212.  
  213. /DefineResource
  214.     { .CheckResource
  215.        { dup [ exch 0 -1 ] exch
  216.          currentglobal
  217.           { false setglobal 2 index UndefineResource    % remove local def if any
  218.         true setglobal
  219.         Instances dup //.emptydict eq
  220.          { pop 3 dict /Instances 1 index def
  221.          }
  222.         if
  223.           }
  224.           { .LocalInstances dup //.emptydict eq
  225.              { pop 3 dict localinstancedict Category 2 index put
  226.          }
  227.         if
  228.           }
  229.          ifelse
  230.          4 2 roll .growput
  231.        }
  232.        { /defineresource load /typecheck signalerror
  233.        }
  234.       ifelse
  235.     } bind
  236. /UndefineResource
  237.     {  { dup 2 index .knownget
  238.           { dup 1 get 1 ge
  239.          { dup 0 null put 1 2 put pop pop }
  240.          { pop exch .undef }
  241.         ifelse
  242.           }
  243.           { pop pop
  244.           }
  245.          ifelse
  246.        }
  247.       currentglobal
  248.        { 2 copy Instances exch exec
  249.        }
  250.       if .LocalInstances exch exec
  251.     } bind
  252. /FindResource
  253.     { dup ResourceStatus
  254.        { pop 1 gt            % not in VM
  255.           { .DoLoadResource
  256.           }
  257.          if
  258.          .GetInstance pop        % can't fail
  259.          0 get
  260.        }
  261.        { /findresource load /undefinedresource signalerror
  262.        }
  263.       ifelse
  264.     } bind
  265. /ResourceStatus
  266.     { dup .GetInstance
  267.        { exch pop dup 1 get exch 2 get true }
  268.        { .ResourceFile
  269.           { closefile 2 -1 true }
  270.           { pop false }
  271.          ifelse
  272.        }
  273.       ifelse
  274.     } bind
  275. /ResourceForAll
  276.     { % **************** Doesn't present instance groups in
  277.       % **************** the correct order yet.
  278.       % We construct a new procedure so we don't have to use
  279.       % static resources to hold the iteration state.
  280.       3 packedarray        % template, proc, scratch
  281.       { exch pop    % stack contains: key, {template, proc, scratch}
  282.         2 copy 0 get .stringmatch
  283.          { 1 index type dup /stringtype eq exch /nametype eq or
  284.         { 2 copy 2 get cvs
  285.           exch 1 get 3 -1 roll pop
  286.         }
  287.         { 1 get
  288.         }
  289.            ifelse exec
  290.          }
  291.          { pop pop
  292.          }
  293.         ifelse
  294.       } /exec cvx 3 packedarray cvx
  295.       % We must pop the resource dictionary off the dict stack
  296.       % when doing the actual iteration, and restore it afterwards.
  297.       currentglobal .LocalInstances length 0 eq or not
  298.        {        % We must do local instances, and do them first.
  299.          /forall cvx 1 index currentdict 3 packedarray cvx
  300.          .LocalInstances 3 1 roll end exec begin
  301.        }
  302.       if
  303.       Instances exch
  304.       /forall cvx currentdict 2 packedarray cvx
  305.       end exec begin
  306.     } bind
  307. /ResourceFileName
  308.     { /GenericResourceDir getsystemparam 
  309.       Category .namestring concatstrings
  310.       /GenericResourcePathSep getsystemparam concatstrings
  311.       .genericrfn
  312.     } bind
  313.  
  314.         % Additional entries
  315.  
  316. % Unfortunately, we can't create the real Instances dictionary now,
  317. % because if someone copies the Generic category (which pp. 95-96 of the
  318. % 2nd Edition Red Book says is legitimate), they'll wind up sharing
  319. % the Instances.  Instead, we have to create Instances on demand,
  320. % just like the entry in localinstancedict.
  321. % We also have to prevent anyone from creating instances of Generic itself.
  322. /Instances //.emptydict
  323.  
  324. /.LocalInstances
  325.     { localinstancedict Category .knownget not { //.emptydict } if
  326.     } bind
  327. /.GetInstance
  328.     { currentglobal
  329.        { Instances exch .knownget }
  330.        { .LocalInstances 1 index .knownget
  331.           { exch pop true }
  332.           { Instances exch .knownget }
  333.          ifelse
  334.        }
  335.       ifelse
  336.     } bind
  337. /.CheckResource
  338.     { true
  339.     } bind
  340. /.DoLoadResource
  341.     { dup vmstatus pop exch pop exch
  342.       .LoadResource
  343.       vmstatus pop exch pop exch sub
  344.       1 index .GetInstance not
  345.        { pop dup /undefinedresource signalerror }    % didn't load
  346.       if
  347.       dup 1 1 put
  348.       2 3 -1 roll put
  349.     } bind
  350. /.LoadResource
  351.     { dup .ResourceFile
  352.        { exch pop currentglobal
  353.           { run }
  354.           { true setglobal { run } stopped false setglobal { stop } if }
  355.          ifelse
  356.        }
  357.        { dup /undefinedresource signalerror
  358.        }
  359.      ifelse
  360.     } bind
  361. /.ResourceFile
  362.     { currentdict /ResourceFileName known
  363.        { mark 1 index 100 string { ResourceFileName }
  364.          .internalstopped
  365.           { cleartomark false }
  366.           { exch pop findlibfile
  367.          { exch pop exch pop true }
  368.          { pop false }
  369.         ifelse
  370.           }
  371.          ifelse
  372.        }
  373.        { false }
  374.       ifelse
  375.     } bind
  376.  
  377. .dicttomark
  378. /Category defineresource pop
  379.  
  380. % Fill in the rest of the Category category.
  381. /Category /Category findresource dup
  382. /Generic /Category findresource begin
  383.  { /FindResource /ResourceForAll /ResourceStatus /UndefineResource /.ResourceFile }
  384.  { dup load put dup } forall
  385. pop readonly pop end
  386.  
  387. (END GENERIC) VMDEBUG
  388.  
  389. % Define the fixed categories.
  390.  
  391. mark
  392.     % Things other than types
  393.  /ColorSpaceFamily
  394.    mark colorspacedict { pop } forall .packtomark
  395.  /Emulator
  396.    mark EMULATORS { cvn } forall .packtomark
  397.  /Filter
  398.    mark filterdict { pop } forall .packtomark
  399.  /IODevice
  400.     % Loop until the .getiodevice gets a rangecheck.
  401.    errordict /rangecheck 2 copy get
  402.    errordict /rangecheck { pop stop } put    % pop the command
  403.    mark 0 { {dup .getiodevice exch 1 add} loop} .internalstopped
  404.    pop pop pop .packtomark
  405.    4 1 roll put
  406.    .clearerror
  407.     % Types
  408.  /setcolorrendering where
  409.   { pop /ColorRenderingType
  410.      {1}
  411.   } if
  412.  /FMapType
  413.    { }    % These must be deferred, because optional features may add some.
  414.  /FontType
  415.    { }    % These must be deferred, because optional features may add some.
  416.  /FormType
  417.    {1}
  418.  /HalftoneType
  419.    {1 2 3 4 5}
  420.  /ImageType
  421.    {1}
  422.  /PatternType
  423.    {1}            % should check for Pattern color space
  424. counttomark 2 idiv
  425.  { mark
  426.  
  427.         % Standard entries
  428.  
  429.         % We'd like to prohibit defineresource,
  430.         % but because optional features may add entries, we can't.
  431.         % We can at least require that the key and value match.
  432.    /DefineResource
  433.     { currentglobal not
  434.        { /defineresource load /invalidaccess signalerror }
  435.        { 2 copy ne
  436.           { /defineresource load /rangecheck signalerror }
  437.           { dup Instances 4 -2 roll .growput }
  438.          ifelse
  439.        }
  440.       ifelse
  441.     } bind
  442.    /UndefineResource
  443.     { /undefineresource load /invalidaccess signalerror } bind
  444.    /FindResource
  445.     { Instances 1 index .knownget
  446.        { exch pop }
  447.        { /findresource load /undefinedresource signalerror }
  448.       ifelse
  449.     } bind
  450.    /ResourceStatus
  451.     { Instances exch known { 0 0 true } { false } ifelse } bind
  452.    /ResourceForAll
  453.     /Generic /Category findresource /ResourceForAll get
  454.  
  455.         % Additional entries
  456.  
  457.    counttomark 2 add -1 roll
  458.    dup length dict dup begin exch { dup def } forall end
  459.         % We'd like to make the Instances readonly here,
  460.         % but because optional features may add entries, we can't.
  461.    /Instances exch
  462.    /.LocalInstances    % used by ResourceForAll
  463.     0 dict def
  464.  
  465.    .dicttomark /Category defineresource pop
  466.  } repeat pop
  467.  
  468. (END FIXED) VMDEBUG
  469.  
  470. % Define the other built-in categories.
  471.  
  472. /.definecategory    % <name> -mark- <key1> ... <valuen> .definecategory -
  473.  { counttomark 2 idiv 2 add        % Instances, Category
  474.    /Generic /Category findresource dup maxlength 3 -1 roll add
  475.    dict .copydict begin
  476.    counttomark 2 idiv { def } repeat pop    % pop the mark
  477.    currentdict end /Category defineresource pop
  478.  } bind def
  479.  
  480. /ColorRendering mark /InstanceType /dicttype .definecategory
  481. /ColorSpace mark /InstanceType /arraytype .definecategory
  482. /Form mark /InstanceType /dicttype .definecategory
  483. /Halftone mark /InstanceType /dicttype .definecategory
  484. /Pattern mark /InstanceType /dicttype .definecategory
  485. /ProcSet mark /InstanceType /dicttype .definecategory
  486.  
  487. (END MISC) VMDEBUG
  488.  
  489. % Define the Encoding category.
  490.  
  491. /Encoding mark
  492.  
  493. /InstanceType /arraytype
  494.  
  495. % Handle already-registered encodings, including lazily loaded encodings
  496. % that aren't loaded yet.
  497.  
  498. /Instances mark
  499.   EncodingDirectory
  500.    { dup length 256 eq { [ exch 0 -1 ] } { pop [null 2 -1] } ifelse
  501.    } forall
  502. .dicttomark
  503.  
  504. /.ResourceFileDict mark
  505.   EncodingDirectory
  506.    { dup length 256 eq { pop pop } { 0 get } ifelse
  507.    } forall
  508. .dicttomark
  509.  
  510. /ResourceFileName
  511.  { .ResourceFileDict 2 index .knownget
  512.     { exch copy exch pop }
  513.     { /Generic /Category findresource /ResourceFileName get exec }
  514.    ifelse
  515.  } bind
  516.  
  517. .definecategory            % Encoding
  518.  
  519. % Make placeholders in level2dict for the redefined Encoding operators,
  520. % so that they will be swapped properly when we switch language levels.
  521.  
  522. /.findencoding /.findencoding load def
  523. /findencoding /findencoding load def
  524. /.defineencoding /.defineencoding load def
  525.  
  526. (END ENCODING) VMDEBUG
  527.  
  528. % Define the Font category.
  529.  
  530. /Font mark
  531.  
  532. /InstanceType /dicttype
  533.  
  534. /DefineResource
  535.     { 2 copy //definefont exch pop
  536.       /Generic /Category findresource /DefineResource get exec
  537.     } bind
  538. /UndefineResource
  539.     { dup //undefinefont
  540.       /Generic /Category findresource /UndefineResource get exec
  541.     } bind
  542. /FindResource
  543.     { dup ResourceStatus
  544.        { pop 1 gt { .loadfont } { .GetInstance pop 0 get } ifelse }
  545.        { .loadfont }
  546.       ifelse
  547.     } bind
  548. /ResourceFileName
  549.     { /FontResourceDir getsystemparam .genericrfn
  550.     } bind
  551.  
  552. /.loadfont
  553.     { dup vmstatus pop exch pop exch
  554.       //findfont exec exch        % findfont is a procedure....
  555.       vmstatus pop exch pop exch sub
  556.         % stack: name font vmused
  557.         % findfont has the prerogative of not calling definefont
  558.         % in certain obscure cases of font substitution.
  559.       2 index .GetInstance
  560.        { dup 1 1 put
  561.          2 3 -1 roll put
  562.        }
  563.        { pop
  564.        }
  565.       ifelse exch pop
  566.     } bind
  567.  
  568. /Instances FontDirectory length 2 mul dict
  569.  
  570. .definecategory            % Font
  571.  
  572. % Redefine font "operators".
  573. /.definefontmap
  574.  { /Font /Category findresource /Instances get
  575.    dup 3 index known
  576.     { pop
  577.     }
  578.     { 2 index
  579.         % Make sure we create the array in global VM.
  580.       .currentglobal true .setglobal
  581.       [null 2 -1] exch .setglobal
  582.       .growput
  583.     }
  584.    ifelse
  585.    //.definefontmap exec
  586.  } bind def
  587.  
  588. % Make sure the old definitions are still in systemdict so that
  589. % they will get bound properly.
  590. systemdict begin
  591.   /.origdefinefont /definefont load def
  592.   /.origundefinefont /undefinefont load def
  593.   /.origfindfont /findfont load def
  594. end
  595. /definefont {
  596.   /Font defineresource
  597. } bind odef
  598. /undefinefont {
  599.   /Font undefineresource
  600. } bind odef
  601. % The Red Book requires that findfont be a procedure, not an operator,
  602. % but it still needs to restore the stacks reliably if it fails.
  603. /.findfontop {
  604.   /Font findresource
  605. } bind odef
  606. /findfont {
  607.   .findfontop
  608. } bind def    % Must be a procedure, not an operator
  609.  
  610. % Remove initialization utilities.
  611. currentdict /.definecategory .undef
  612. currentdict /.emptydict .undef
  613.  
  614. end                % level2dict
  615.  
  616. % Convert deferred resources after we finally switch to Level 2.
  617.  
  618. /.fixresources {
  619.     % Encoding resources
  620.  EncodingDirectory
  621.    { dup length 256 eq
  622.       { /Encoding defineresource pop }
  623.       { pop pop }
  624.      ifelse
  625.    } forall
  626.   /.findencoding { /Encoding findresource } bind def
  627.   /findencoding /.findencoding load odef
  628.   /.defineencoding { /Encoding defineresource pop } bind def
  629.     % ColorRendering resources and ProcSet
  630.   systemdict /ColorRendering .knownget {
  631.     /ColorRendering exch /ProcSet defineresource pop
  632.     systemdict /ColorRendering undef
  633.     /DefaultColorRendering currentcolorrendering /ColorRendering
  634.       defineresource pop
  635.     % FontType and FMapType resources
  636.   buildfontdict { pop dup /FontType defineresource pop } forall
  637.   mark
  638.     buildfontdict 0 known { 2 3 4 5 6 7 8 } if
  639.     buildfontdict 9 known { 9 } if
  640.   counttomark { dup /FMapType defineresource pop } repeat pop
  641.   } if
  642.     % clean up
  643.   systemdict /.fixresources undef
  644. } bind def
  645.